#ifndef __KCP_CLIENT_H__
#define __KCP_CLIENT_H__

#include "eventloop.h"

#include "ikcp.h"

#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#include <functional>

namespace Gazella {

typedef std::function<void(const std::string&)> kcp_client_recv_cb_t;

class KcpClient {
public:
    KcpClient();
    ~KcpClient();

    bool init(IUINT32 conv, const std::string& remote_ip, const int remote_port);
    void set_waitsnd_threshold(int waitsnd);

    void send_message(const std::string& message);

    void set_recv_cb(kcp_client_recv_cb_t cb);

    int get_sd();
    struct sockaddr_in& get_saddr();

private:
    void __ikcp_update_timer_callback(ev::timer& w, int revents);
    void __udp_recv_callback(ev::io& w, int revents);

    bool __create_udp_client(const std::string& remote_ip, const int remote_port);

    void __new_kcp();
    void __del_kcp();
    void __reinit();

private:
    int m_sd; //udp

    std::string m_remote_ip;
    int m_remote_port;
    struct sockaddr_in m_saddr;

    uint32_t m_conv;
    int m_waitsnd_threshold = 32;

    ikcpcb *m_ikcp;

    ev::timer m_timer;
    ev::io m_rx_io;

    kcp_client_recv_cb_t m_kcp_recv_cb;
};
}

#endif